package com.syl.starter.itools.common.utils;

import com.syl.starter.itools.base.constants.BaseConstant;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.web.util.HtmlUtils;

import java.util.UUID;

/**
 * 资料文档 https://blog.csdn.net/xuxiaoxie/article/details/52095930
 *
 * lang3 StringUtils 的扩展
 * @author syl
 * @create 2018-09-04 18:19
 **/
public class StringUtils extends org.apache.commons.lang3.StringUtils{

    /**
     * 字符串中是否存在指定元素
     * StringUtils.contains("ab", null)                 = false
     * StringUtils.contains("ab", null, "a")            = false
     * StringUtils.contains("ab", "c", "a")             = false
     * StringUtils.contains("abc", "c", "a")        = true
     * @param string
     * @param substring
     * @return
     */
    public static boolean contains(String string, String... substring){
        for (String sub : substring) {
            if(sub == null)
                return false;
            boolean contains = StringUtils.contains(string, sub);
            if(!contains)
                return false;
        }
        return true;
    }

    /**
     * 更强力的判断字符串是否为空 字符串为"null"都视为空 以js规则判定
     * StringUtils.isEmpty(null)      = true
     * StringUtils.isEmpty("")        = true
     * StringUtils.isEmpty("undefined")        = true
     * StringUtils.isEmpty("null")        = true
     * StringUtils.isEmpty("NULL")        = true
     * StringUtils.isEmpty(" ")       = false
     * StringUtils.isEmpty("bob")     = false
     * StringUtils.isEmpty("  bob  ") = false
     *
     * @return 是否为空
     */
    public static boolean isEmptyStrong(final CharSequence cs) {
        return isEmpty(cs) || equalsAny(cs, "null", "NULL", "undefined");
    }

    /**
     * 更强力的判断字符串是否不为空 字符串为"null"都视为空 以js规则判定
     * StringUtils.isEmpty(null)      = false
     * StringUtils.isEmpty("")        = false
     * StringUtils.isEmpty("undefined")        = false
     * StringUtils.isEmpty("null")        = false
     * StringUtils.isEmpty("NULL")        = false
     * StringUtils.isEmpty(" ")       = true
     * StringUtils.isEmpty("bob")     = true
     * StringUtils.isEmpty("  bob  ") = true
     *
     * @return 是否不为空
     */
    public static boolean isNotEmptyStrong(final CharSequence cs) {
        return !isEmptyStrong(cs);
    }

    /**
     * 更强力的判断字符串是否为空 字符串为"null"都视为空 以js规则判定
     * StringUtils.isAllEmptyStrong(null)      = true
     * StringUtils.isAllEmptyStrong("", null)        = true
     * StringUtils.isAllEmptyStrong("undefined")        = true
     * StringUtils.isAllEmptyStrong("null")        = true
     * StringUtils.isAllEmptyStrong("NULL")        = true
     * StringUtils.isAllEmptyStrong(" ")       = false
     * StringUtils.isAllEmptyStrong("null", "bob")     = false
     * StringUtils.isAllEmptyStrong("null", "NULL") = true
     *
     * @return 是否为空
     */
    public static boolean isAllEmptyStrong(final CharSequence... css) {
        if (ArrayUtils.isEmpty(css)) {
            return true;
        }
        for (final CharSequence cs : css) {
            if (isNotEmptyStrong(cs)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 更强力的判断字符串是否为空 字符串为"null"都视为空 以js规则判定
     * StringUtils.isAnyEmptyStrong(null)      = true
     * StringUtils.isAnyEmptyStrong("", null)        = true
     * StringUtils.isAnyEmptyStrong("undefined")        = true
     * StringUtils.isAnyEmptyStrong("null")        = true
     * StringUtils.isAnyEmptyStrong("NULL")        = true
     * StringUtils.isAnyEmptyStrong(" ")       = false
     * StringUtils.isAnyEmptyStrong("null", "bob")     = true
     * StringUtils.isAnyEmptyStrong("abc", "bob") = false
     *
     * @return 是否为空
     */
    public static boolean isAnyEmptyStrong(CharSequence... css) {
        if (ArrayUtils.isEmpty(css)) {
            return false;
        }
        for (CharSequence string : css){
            if (isEmptyStrong(string)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 去除空格后是否空
     * @param string
     * @return
     */
    public static boolean isEmptyAndTrim(String string){
        return isEmpty(StringUtils.trim(string));
    }

    /**
     * 去除空格后比较
     * @return
     */
    public static boolean equalsAndTrim(String string1, String string2) {
        string1 = trim(string1);
        string2 = trim(string2);
        return equals(string1, string2);
    }

    /**
     * 包装split 避免空指针
     * StringUtils.split(null, *)         = []
     * StringUtils.split("", *)           = []
     * StringUtils.split("abc def", null) = ["abc", "def"]
     * StringUtils.split("abc def", " ")  = ["abc", "def"]
     * StringUtils.split("abc  def", " ") = ["abc", "def"]
     * StringUtils.split("ab:cd:ef", ":") = ["ab", "cd", "ef"]
     * @param str
     * @param separatorChars
     * @return
     */
    public static String[] split(final String str, final String separatorChars) {
        if(StringUtils.isEmpty(str))
            return new String[]{};
        return org.apache.commons.lang3.StringUtils.split(str, separatorChars);
    }

    /**
     * 包装toString 避免空指针
     * StringUtils.toString(null)         = null
     * @param object obj
     * @return obj为空时返回null
     */
    public static String toString(Object object){
        return toString(object, null);
    }

    /**
     * toString 当对象为空时返回 defaultStr
     * StringUtils.toString(null, "abc")         = "abc"
     * @param object obj
     * @param defaultStr 默认值
     * @return obj为空时返回默认值
     */
    public static String toString(Object object, String defaultStr){
        if(object == null)
            return defaultStr;
        return object.toString();
    }

    /**
     * 截取以separator分割第一级的字符串
     * StringUtils.substringFirstStep(null, *)         = null
     * StringUtils.substringFirstStep("a,b", ",")         = "a"
     *
     * @param string 目标字符串
     * @param separator 分隔符
     * @return
     */
    public static String substringFirstStep(String string, String separator){
        if(StringUtils.isEmpty(string))
            return null;
        return split(string, separator)[0];
    }

    /**
     * 截取以separator分割最后一级的字符串
     * StringUtils.substringLastStep(null, *)         = null
     * StringUtils.substringLastStep("a,b", ",")         = "b"
     *
     * @param string 目标字符串
     * @param separator 分隔符
     * @return
     */
    public static String substringLastStep(String string, CharSequence separator){
        if(StringUtils.isEmpty(string))
            return null;
        if(separator.equals(BaseConstant.DOT_ESCAPE))
            separator = BaseConstant.DOT; //这里是因为 lastIndexOf 这里已经转义了
        return string.substring(lastIndexOf(string, separator)+1);
    }

    /**
     * 第一个字符大写
     * StringUtils.firstCharUpper(null)         = null
     * StringUtils.firstCharUpper("aaa")         = "Aaa"
     *
     * @param string
     * @return
     */
    public static String firstCharUpper(String string){
        if(StringUtils.isEmpty(string))
            return null;
        return String.valueOf(string.charAt(0)).toUpperCase() + string.substring(1);
    }

    /**
     * 第一个字符小写
     * StringUtils.firstCharLower(null)         = null
     * StringUtils.firstCharLower("AAA")         = "aAA"
     *
     * @param string
     * @return
     */
    public static String firstCharLower(String string){
        if(StringUtils.isEmpty(string))
            return null;
        return String.valueOf(string.charAt(0)).toLowerCase() + string.substring(1);
    }

    /**
     * 获取uuid
     * StringUtils.getUUID(true)         = a4cbe92697dc47df-b0aeac40f6f69977
     * StringUtils.getUUID(false)         = a4cbe926-97dc-47df-b0ae-ac40f6f69977
     *
     * @param b 是否过滤
     * @return
     */
    public static String getUUID(boolean b){
        String uuid = UUID.randomUUID().toString();
        if(b)
            return uuid.replace(BaseConstant.BAR_SEPARATOR, BaseConstant.EMPTY_STRING);
        return uuid;
    }

    /**
     * 最后一位包含指定字符则移除
     * StringUtils.removeLast(null, *)      = null
     * StringUtils.removeLast("a/b", null)  = "a/b"
     * StringUtils.removeLast("a/b", "/")   = "a/b"
     * StringUtils.removeLast("a/b", "/")   = "a/b"
     *
     * @param string 字符串
     * @param separator 字符
     * @return
     */
    public static String removeLast(String string, String separator){
        if (StringUtils.isEmpty(string)) return null;
        if (StringUtils.isEmpty(separator)) return  string;
        int lastIndexOf = string.lastIndexOf(separator);
        int length = string.length() - separator.length();
        return length != lastIndexOf ? string : string.substring(0, length);
    }

    /**
     * 最后一位必定包含指定字符
     * StringUtils.mustLast(null, *)      = null
     * StringUtils.mustLast("a/b", null)  = "a/b"
     * StringUtils.mustLast("a/b", "/")   = "a/b/"
     *
     * @param string
     * @param separator
     * @return
     */
    public static String mustLast(String string, String separator){
        if (StringUtils.isEmpty(string)) return null;
        if (StringUtils.isEmpty(separator)) return  string;
        int lastIndexOf = string.lastIndexOf(separator);
        int length = string.length() - 1;
        return length == lastIndexOf ? string : string + separator;
    }

    /**
     * 手机号加敏
     * StringUtils.phoneSensitive(null)      = null
     * StringUtils.phoneSensitive("aaa")     = "aaa"
     * StringUtils.phoneSensitive("18666666666")     = "186****6666"
     *
     * @param phone
     *
     * @return
     */
    public static String phoneSensitive(String phone){
        if(isEmpty(phone)){
            return null;
        }
        if(phone.length() < 11)
            return phone;
        return phone.substring(0, 3) + "****" + phone.substring(7, 11);
    }

    /**
     * 页面提交数据转义 避免xss用
     * StringUtils.htmlEscape(null)      = null
     * StringUtils.htmlEscape("null")      = null
     * StringUtils.htmlEscape("alert(\"123\")")      = alert(&quot;123&quot;)
     *
     * @param string
     * @return
     */
    public static String htmlEscape(String string){
        return StringUtils.isEmpty(string) || "null".equals(string) ? null : HtmlUtils.htmlEscape(string);
    }

    /**
     * 字符串转驼峰
     * StringUtils.underlineToCamel(null, false)     = null
     * StringUtils.underlineToCamel("abc", false)     = "abc"
     * StringUtils.underlineToCamel("abc", true)     = "Abc"
     * StringUtils.underlineToCamel("a_b_c", false)     = "aBC"
     * StringUtils.underlineToCamel("a_b_c", true)     = "ABC"
     *
     * @param string 要转换的字符
     * @param initial 是否首字母大写
     * @return
     */
    public static String underlineToCamel(String string, boolean initial){
        return underlineToCamel(string, null, initial);
    }

    /**
     * 获取上传文件的文件名后缀
     * @param originalFilename 上传的原始文件名
     * @return 文件类型后缀
     */
    public static String getUploadFileSuffix(String originalFilename){
        return BaseConstant.DOT + substringLastStep(originalFilename, BaseConstant.DOT);
    }

    /**
     * 字符串转驼峰
     * StringUtils.underlineToCamel(null, *, false)     = null
     * StringUtils.underlineToCamel("abc", *, false)     = "abc"
     * StringUtils.underlineToCamel("abc", *, true)     = "Abc"
     * StringUtils.underlineToCamel("a_b_c", null, false)     = "aBC"
     * StringUtils.underlineToCamel("a_b_c", null, true)     = "ABC"
     * StringUtils.underlineToCamel("a_b_c", "*", true)     = "A_b_c"
     *
     * @param string 要转换的字符
     * @param searchSeq 要替换的字符 可以为正则表达式 默认为[-_]
     * @param initial 是否首字母大写
     * @return
     */
    public static String underlineToCamel(String string, String searchSeq, boolean initial) {
        searchSeq = searchSeq == null ? "[-_]" : searchSeq;
        if(!RegexUtils.test(string, searchSeq)){
            return initial ? firstCharUpper(string) : string;
        }
        if (StringUtils.isNotEmpty(string)) {
            StringBuilder sb = new StringBuilder();
            if(initial)
                sb.append(String.valueOf(string.charAt(0)).toUpperCase());
            else
                sb.append(String.valueOf(string.charAt(0)).toLowerCase());
            char[] param = string.toCharArray();
            for (int i = 1; i < string.length(); i++) {
                char c = string.charAt(i);
                if (RegexUtils.test(String.valueOf(c), searchSeq)) {
                    if (++i < string.length()) {
                        sb.append(Character.toUpperCase(param[i]));
                    }
                } else {
                    sb.append(c);
                }
            }
            return sb.toString();
        }
        return null;
    }

}
